package com.sxr.servlet.util;

import com.sxr.file.FileResponse;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;

/**
 * Servlet响应写入工具
 * 将业务响应对象写入HttpServletResponse
 *
 * @author SXR
 * @since 1.0.0
 */
public class ServletResponseWriter {

    private static final int BUFFER_SIZE = 8192;

    /**
     * 写入文件响应
     *
     * @param fileResponse 文件响应对象
     * @param response HTTP响应
     * @throws IOException IO异常
     */
    public void writeFileResponse(FileResponse fileResponse, HttpServletResponse response) throws IOException {

        // 设置状态码
        response.setStatus(fileResponse.getStatusCode());

        if (!fileResponse.isSuccess()) {
            // 错误响应
            writeErrorResponse(fileResponse, response);
            return;
        }

        // 设置响应头
        setResponseHeaders(fileResponse, response);

        // 设置内容长度
        if (fileResponse.getContentLength() > 0) {
            response.setContentLengthLong(fileResponse.getContentLength());
        }

        // 写入文件内容
        writeFileContent(fileResponse, response);
    }

    /**
     * 写入JSON响应
     *
     * @param data 数据对象
     * @param response HTTP响应
     * @throws IOException IO异常
     */
    public void writeJsonResponse(Map<String, String> data, HttpServletResponse response) throws IOException {
        response.setStatus(HttpServletResponse.SC_OK);
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");

        // 构建JSON字符串
        StringBuilder json = new StringBuilder();
        json.append("{");

        boolean first = true;
        for (Map.Entry<String, String> entry : data.entrySet()) {
            if (!first) {
                json.append(",");
            }
            json.append("\"").append(escapeJson(entry.getKey())).append("\":");
            json.append("\"").append(escapeJson(entry.getValue())).append("\"");
            first = false;
        }

        json.append("}");

        response.getWriter().write(json.toString());
        response.getWriter().flush();
    }

    /**
     * 写入错误响应
     */
    private void writeErrorResponse(FileResponse fileResponse, HttpServletResponse response) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");

        String errorJson = "{\"success\":false,\"error\":\"" +
                          escapeJson(fileResponse.getErrorMessage()) + "\"}";

        response.getWriter().write(errorJson);
        response.getWriter().flush();
    }

    /**
     * 设置响应头
     */
    private void setResponseHeaders(FileResponse fileResponse, HttpServletResponse response) {
        // 设置基本响应头
        for (Map.Entry<String, String> header : fileResponse.getHeaders().entrySet()) {
            response.setHeader(header.getKey(), header.getValue());
        }

        // 设置安全相关的响应头
        response.setHeader("X-Content-Type-Options", "nosniff");
        response.setHeader("X-Frame-Options", "SAMEORIGIN");
        response.setHeader("X-XSS-Protection", "1; mode=block");
        // 跨域相关的内容
        response.setHeader("Access-Control-Allow-Origin", "*"); // 或 "*"
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true"); // 如果你支持 cookie 跨域的话
        // 设置缓存控制
        if (!response.containsHeader("Cache-Control")) {
            response.setHeader("Cache-Control", "private, max-age=3600");
        }
    }

    /**
     * 写入文件内容
     */
    private void writeFileContent(FileResponse fileResponse, HttpServletResponse response) throws IOException {
        InputStream inputStream = fileResponse.getInputStream();
        if (inputStream == null) {
            return;
        }

        try (InputStream input = inputStream;
             OutputStream output = response.getOutputStream()) {

            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead;

            while ((bytesRead = input.read(buffer)) != -1) {
                output.write(buffer, 0, bytesRead);

                // 定期刷新输出流，实现流式传输
                if (bytesRead == BUFFER_SIZE) {
                    output.flush();
                }
            }

            output.flush();

        } catch (IOException e) {
            // 记录日志但不抛出异常，避免影响其他请求
            throw e;
        }
    }

    /**
     * JSON字符串转义
     */
    private String escapeJson(String str) {
        if (str == null) {
            return "";
        }
        return str.replace("\\", "\\\\")
                  .replace("\"", "\\\"")
                  .replace("\n", "\\n")
                  .replace("\r", "\\r")
                  .replace("\t", "\\t")
                  .replace("\b", "\\b")
                  .replace("\f", "\\f");
    }
}
